/*

The contents of this web application are subject to the Mozilla Public License Version 1.1 (the "License"); you may not use this web application except in compliance with the License. 
You may obtain a copy of the License at http://www.mozilla.org/MPL/.

Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. 
See the License for the specific language governing rights and limitations under the License.

The Original Code is owned by and the Initial Developer of the Original Code is Composite A/S (Danish business reg.no. 21744409). All Rights Reserved

Section 11 of the License is EXPRESSLY amended to include a provision stating that any dispute, including but not limited to disputes related to the enforcement of the License, to which Composite A/S as owner of the Original Code, as Initial Developer or in any other role, becomes a part to shall be governed by Danish law and be initiated before the Copenhagen City Court ("K�benhavns Byret")
                        
*/

using System;
using System.Collections.Generic;
using System.Linq;
using Composite.Data;
using Composite.Core.Linq;
using Composite.Data.Types;
using Composite.C1Console.Elements;
using Composite.C1Console.Elements.Plugins.ElementProvider;
using Composite.Core.ResourceSystem;
using Composite.Core.ResourceSystem.Icons;
using Composite.C1Console.Security;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using Composite.C1Console.Workflow;
using Composite.Core.Types;


namespace Composite.Plugins.Elements.ElementProviders.UserGroupElementProvider
{
    [ConfigurationElementType(typeof(NonConfigurableHooklessElementProvider))]
    internal sealed class UserGroupElementProvider : IHooklessElementProvider, IAuxiliarySecurityAncestorProvider
    {
        private ElementProviderContext _elementProviderContext;

        public static ResourceHandle RootOpenIcon { get { return GetIconHandle("usergroups-rootfolder-open"); } }
        public static ResourceHandle RootClosedIcon { get { return GetIconHandle("usergroups-rootfolder-closed"); } }
        public static ResourceHandle UserGroupIcon { get { return GetIconHandle("usergroups-usergroup"); } }
        public static ResourceHandle AddUserGroupIcon { get { return GetIconHandle("usergroups-addusergroup"); } }
        public static ResourceHandle EditUserGroupIcon { get { return GetIconHandle("usergroups-editusergroup"); } }
        public static ResourceHandle DeleteUserGroupIcon { get { return GetIconHandle("usergroups-deleteusergroup"); } }

        private static readonly ActionGroup PrimaryActionGroup = new ActionGroup(ActionGroupPriority.PrimaryHigh);
        private static readonly PermissionType[] AddNewUserGroupPermissionTypes = new PermissionType[] { PermissionType.Administrate };
        private static readonly PermissionType[] EditUserGroupPermissionTypes = new PermissionType[] { PermissionType.Administrate };
        private static readonly PermissionType[] DeleteUserGroupPermissionTypes = new PermissionType[] { PermissionType.Administrate };


        public UserGroupElementProvider()
        {
            AuxiliarySecurityAncestorFacade.AddAuxiliaryAncestorProvider<DataEntityToken>(this);
        }



        public ElementProviderContext Context
        {
            set
            {
                _elementProviderContext = value;
            }
        }



        public IEnumerable<Element> GetRoots(SearchToken seachToken)
        {
            int userGroupCount = DataFacade.GetData<IUserGroup>().Count();

            Element element = new Element(_elementProviderContext.CreateElementHandle(new UserGroupElementProviderRootEntityToken()))
            {
                VisualData = new ElementVisualizedData
                {
                    Label = StringResourceSystemFacade.GetString("Composite.Plugins.UserGroupElementProvider", "UserGroupElementProvider.RootLabel"),
                    ToolTip = StringResourceSystemFacade.GetString("Composite.Plugins.UserGroupElementProvider", "UserGroupElementProvider.RootToolTip"),
                    HasChildren = userGroupCount > 0,
                    Icon = UserGroupElementProvider.RootClosedIcon,
                    OpenedIcon = UserGroupElementProvider.RootOpenIcon
                }
            };

            element.AddAction(new ElementAction(new ActionHandle(new WorkflowActionToken(WorkflowFacade.GetWorkflowType("Composite.Plugins.Elements.ElementProviders.UserGroupElementProvider.AddNewUserGroupWorkflow"), AddNewUserGroupPermissionTypes)))
            {
                VisualData = new ActionVisualizedData
                {
                    Label = StringResourceSystemFacade.GetString("Composite.Plugins.UserGroupElementProvider", "UserGroupElementProvider.AddNewUserGroupLabel"),
                    ToolTip = StringResourceSystemFacade.GetString("Composite.Plugins.UserGroupElementProvider", "UserGroupElementProvider.AddNewUserGroupToolTip"),
                    Icon = UserGroupElementProvider.AddUserGroupIcon,
                    Disabled = false,
                    ActionLocation = new ActionLocation
                    {
                        ActionType = ActionType.Add,
                        IsInFolder = false,
                        IsInToolbar = true,
                        ActionGroup = PrimaryActionGroup
                    }
                }
            });

            yield return element;
        }



        public IEnumerable<Element> GetChildren(EntityToken entityToken, SearchToken seachToken)
        {
            if ((entityToken is UserGroupElementProviderRootEntityToken) == false) return new Element[] { };

            IEnumerable<IUserGroup> userGroups =
                (from ug in DataFacade.GetData<IUserGroup>()
                 orderby ug.Name
                 select ug).Evaluate();

            List<Element> elements = new List<Element>();

            foreach (IUserGroup userGroup in userGroups)
            {
                Element element = new Element(_elementProviderContext.CreateElementHandle(userGroup.GetDataEntityToken()))
                {
                    VisualData = new ElementVisualizedData
                    {
                        Label = userGroup.Name,
                        ToolTip = userGroup.Name,
                        HasChildren = false,
                        Icon = UserGroupElementProvider.UserGroupIcon,
                        OpenedIcon = UserGroupElementProvider.UserGroupIcon
                    }
                };

                element.AddAction(new ElementAction(new ActionHandle(new WorkflowActionToken(WorkflowFacade.GetWorkflowType("Composite.Plugins.Elements.ElementProviders.UserGroupElementProvider.EditUserGroupWorkflow"), EditUserGroupPermissionTypes)))
                {
                    VisualData = new ActionVisualizedData
                    {
                        Label = StringResourceSystemFacade.GetString("Composite.Plugins.UserGroupElementProvider", "UserGroupElementProvider.EditUserGroupLabel"),
                        ToolTip = StringResourceSystemFacade.GetString("Composite.Plugins.UserGroupElementProvider", "UserGroupElementProvider.EditUserGroupToolTip"),
                        Icon = UserGroupElementProvider.EditUserGroupIcon,
                        Disabled = false,
                        ActionLocation = new ActionLocation
                        {
                            ActionType = ActionType.Edit,
                            IsInFolder = false,
                            IsInToolbar = true,
                            ActionGroup = PrimaryActionGroup
                        }
                    }
                });

                element.AddAction(new ElementAction(new ActionHandle(new WorkflowActionToken(WorkflowFacade.GetWorkflowType("Composite.Plugins.Elements.ElementProviders.UserGroupElementProvider.DeleteUserGroupWorkflow"), DeleteUserGroupPermissionTypes)))
                {
                    VisualData = new ActionVisualizedData
                    {
                        Label = StringResourceSystemFacade.GetString("Composite.Plugins.UserGroupElementProvider", "UserGroupElementProvider.DeleteUserGroupLabel"),
                        ToolTip = StringResourceSystemFacade.GetString("Composite.Plugins.UserGroupElementProvider", "UserGroupElementProvider.DeleteUserGroupToolTip"),
                        Icon = UserGroupElementProvider.DeleteUserGroupIcon,
                        Disabled = false,
                        ActionLocation = new ActionLocation
                        {
                            ActionType = ActionType.Delete,
                            IsInFolder = false,
                            IsInToolbar = true,
                            ActionGroup = PrimaryActionGroup
                        }
                    }
                });

                elements.Add(element);
            }

            return elements;
        }



        public Dictionary<EntityToken, IEnumerable<EntityToken>> GetParents(IEnumerable<EntityToken> entityTokens)
        {
            Dictionary<EntityToken, IEnumerable<EntityToken>> result = new Dictionary<EntityToken, IEnumerable<EntityToken>>();

            foreach (EntityToken entityToken in entityTokens)
            {
                DataEntityToken dataEntityToken = entityToken as DataEntityToken;

                Type type = dataEntityToken.InterfaceType;
                if (type != typeof(IUserGroup)) continue;

                UserGroupElementProviderRootEntityToken newEntityToken = new UserGroupElementProviderRootEntityToken();

                result.Add(entityToken, new EntityToken[] { newEntityToken });
            }

            return result;
        }



        private List<EntityTokenHook> CreateHooks()
        {
            IEnumerable<EntityToken> userGroupsEntityTokens =
                from ug in DataFacade.GetData<IUserGroup>()
                select (EntityToken)ug.GetDataEntityToken();

            EntityTokenHook hook = new EntityTokenHook(new UserGroupElementProviderRootEntityToken());
            hook.AddHookies(userGroupsEntityTokens);

            return new List<EntityTokenHook> { hook };
        }



        private static ResourceHandle GetIconHandle(string name)
        {
            return new ResourceHandle(BuildInIconProviderName.ProviderName, name);
        }
    }
}
